package com.example.common.config;

import com.example.common.dto.Result;
import com.example.common.exception.BusinessException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Objects;

/**
 * 全局异常处理器
 *
 * @author cui haida
 * @version JDK 8
 * 2025/8/4
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理业务异常 - if the exception is BusinessException, will execute this method
     *
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(BusinessException.class)
    public Result<?> handleBusinessException(BusinessException e) {
        return Result.error(e.getCode(), e.getMessage());
    }

    /**
     * 处理参数校验异常 - if the exception is MethodArgumentNotValidException, will execute this method
     *
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        StringBuilder error = new StringBuilder();
        BindingResult bindingResult = e.getBindingResult();

        if (bindingResult.hasErrors()) {
            for (ObjectError allError : bindingResult.getAllErrors()) {
                error.append(allError.getDefaultMessage()).append(";");
            }
            return Result.error(400, error.toString());
        }

        String failMessage = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
        return Result.error(400, failMessage);
    }

    /**
     * 处理其他异常 - if the exception is not BusinessException, will execute this method
     *
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(Exception.class)
    public Result<?> handleException(Exception e) {
        return Result.error(500, "Internal Server Error: " + e.getMessage());
    }
}